package com.she.component.adapter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;

import com.she.component.adapter.iface.IGenView;

public class GeneralAdapter extends BaseAdapter{
	
	final int TYPE_ARRAYLIST     = 0;
	final int TYPE_LINKEDHASHMAP = 1;
	final int TYPE_CURSOR        = 2;
	
	int      mDataType = -1;
	Object   mData;
	IGenView mGenerator;
	Context  mContext;
	
	boolean mHasFooter = false;
	
	public GeneralAdapter(Context context, IGenView generator) {
		this.mGenerator = generator;
		this.mContext   = context;
	}
	
	public GeneralAdapter(Context context, IGenView generator, int dummys) {
		this.mGenerator = generator;
		this.mContext   = context;
		if(dummys > 0) {
			List<Object> dummyData = new ArrayList<Object>();
			for(int i = 0; i < dummys; i++) {
				dummyData.add(new Object());
			}
			setData(dummyData);
		}
	}
	
	public void setListView(ListView listView) {
		this.mGenerator.setListview(listView);
	}
	
	public Object getData() {
		return mData;
	}
	
	public void setData(Object object) {
		setData(object, false);
	}
	
	public void setData(Object object, boolean hasFooter)   {
		mHasFooter = hasFooter;
		// Multiple data list without header
		if(object instanceof ArrayList)          mDataType = TYPE_ARRAYLIST;
		else if(object instanceof LinkedHashMap) mDataType = TYPE_LINKEDHASHMAP;
		else if(object instanceof Cursor)        mDataType = TYPE_CURSOR;
		mData = object;
	}
	
//	public int getCountWithoutHeader() {
//		int count = 0;
//		switch(mDataType) {
//			case TYPE_ARRAYLIST:
//				count = ((ArrayList)mData).size();
//				break;
//			case TYPE_LINKEDHASHMAP:
//				Iterator iterator = ((LinkedHashMap)mData).entrySet().iterator();
//				while(iterator.hasNext()) {
//					Entry entry = (Entry)iterator.next();
//					if(entry.getValue() instanceof List) {
//						count = count + ((List)entry.getValue()).size();
//					}
//				}
//				break;
//			case TYPE_CURSOR:
//				count = ((Cursor)mData).getCount();
//				break;
//			default:
//				break;
//		}
//		return count;
//	}
	
	@Override
	public int getCount() {
		int count = 0;
		switch(mDataType) {
			case TYPE_ARRAYLIST:
				count = ((ArrayList<?>)mData).size();
				break;
			case TYPE_LINKEDHASHMAP:
				Iterator<?> iterator = ((LinkedHashMap<?,?>)mData).entrySet().iterator();
				while(iterator.hasNext()) {
					Entry<?,?> entry = (Entry<?,?>)iterator.next();
					if(entry.getValue() instanceof List) {
						count = count + 1 + ((List<?>)entry.getValue()).size();
					}
				}
				break;
			case TYPE_CURSOR:
				count = ((Cursor)mData).getCount(); 
				break;
			default:
				break;
		}
		if(mHasFooter) count++;
		return count;
	}

	@Override
	public Object getItem(int position) {
		Object object = null;
		switch(mDataType) {
			case TYPE_ARRAYLIST:
				if(position < ((ArrayList<?>)mData).size()) object = ((ArrayList<?>)mData).get(position); 
				break;
			case TYPE_LINKEDHASHMAP:
				// Return value may be key or element
				LinkedHashMap<?,?> map = (LinkedHashMap<?,?>)mData;
				Iterator<?> it = map.entrySet().iterator();
				int index = position;
				while(it.hasNext()) {
					Entry<?,?> entry = (Entry<?,?>)it.next();
					if(entry.getValue() instanceof List) {
						if(index == 0)                                    object = entry.getKey();
						else if(index <= ((List<?>)entry.getValue()).size()) object = ((List<?>)entry.getValue()).get(index-1);
						else                                              index = index - ((List<?>)entry.getValue()).size() - 1;
					}
				}
				break;
			case TYPE_CURSOR:
				if(position <= ((Cursor)mData).getCount()) object = ((Cursor)mData).moveToPosition(position);
				break;
			default:
				break;
		}
		return object;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		return mGenerator.setup(mContext, position, convertView, parent, mData);
	}		
}
